<?php

class Files
{
	public $root = WWW_ROOT;
	
	function __construct($root=null)
	{
		if (!is_null($root))
			$this->root = $root;
	}
	
	function exists($path)
	{
		return file_exists($this->root.$path);
	}
	
	function mkdir($path)
	{
		return mkdir($this->root.$path);
	}
	
	function & ls($path, $recursive=false)
	{
		$_path = $this->root.$path;
		
#		if (!isset($this->finfo))
#			$this->finfo = new finfo(FILEINFO_MIME, '/usr/share/file/magic');
		
		if (is_dir($_path) and ($dh = opendir($_path)))
		{
			$data = array(
				'dirs'  => array(),
				'files' => array()
			);
			
			while (false !== ($f = readdir($dh)))
			{
				if ($f == '.' or ($f == '..' and $path == '/'))
					continue;
				if (is_dir($_path.$f))
					array_push($data['dirs'], $f);
				else
					array_push($data['files'], $f);
			}
			closedir($dh);
			
			array_multisort($data['dirs']);
			array_multisort($data['files']);
		}
		elseif (is_file($_path))
		{
			$data = stat($_path);
			$data['mimetype'] = $this->mimetype($_path);
#			$data['mimetype'] = mime_content_type($_path);
#			$data['mimetype'] = $this->finfo->file($_path);
		}
		return $data;
	}
	
	function mimetype($path)
	{
		if (preg_match('/\.([^.]+)$/', $path, $match))
		{
			switch(strtolower($match[1]))
			{
				# image
				case 'jpeg': case 'jpg': return 'image/jpeg';
				case 'png':     return 'image/gif';
				case 'gif':     return 'image/gif';
				case 'svg':     return 'image/svg+xml';
				
				# video
				case 'flv':     return 'video/x-flv';
				
				# audio
				case 'mp3':     return 'audio/mpeg';
				case 'ogg':     return 'application/ogg';
				
				# web
				case 'swf':     return 'application/x-shockwave-flash';
				case 'html':    return 'text/html';
				case 'css':     return 'text/css';
				case 'js':      return 'text/javascript';
				case 'vrml':    return 'model/vrml';
				
				# others
				case 'pdf':     return 'application/pdf';
				case 'txt':     return 'text/plain';
				case 'psd':     return 'application/x-photoshop';
				case 'torrent': return 'application/x-bittorrent';
			}
		}
	}
	
	/**
	 * Deletes either a file or a directory (recursively).
	 */
	function rm($path)
	{
		$_path = $this->root.$path;
		
		// a file?
		if (is_file($_path))
			return unlink($_path);
		
		// a directory?
		if (is_dir($_path))
			return $this->rmdir($path);
		
		// wtf?
		throw new Exception(sprintf(_('%s: unknown file type.', $path)));
	}
	
	/**
	 * Recursively deletes a directory.
	 */
	function rmdir($path)
	{
		$_path = $this->root.$path;
		
		if (is_dir($_path) and ($dh = opendir($_path)))
		{
			while (false !== ($f = readdir($dh)))
			{
				if ($f == '.' or $f == '..')
					continue;
				
				if (is_dir($_path.$f))
				{
					if (!$this->rmdir($path.$f.DS))
						return false;
				}
				else
				{
					if (!unlink($_path.$f))
						return false;
				}
			}
			closedir($dh);
			return rmdir($_path);
		}
		elseif (file_exists($_path)) {
			return unlink($_path);
		}
		return true;
	}
	
	/**
	 * Recursively copies a directory.
	 */ 
	function copydir($src, $dest)
	{
		$_src  = $this->root.$src.DS;
		$_dest = $this->root.$dest.DS;
		
		if (!is_dir($_dest) and !mkdir($_dest))
			return false;
		
		if ($dh = opendir($_src))
		{
			while(false !== ($f = readdir($dh)))
			{
				if ($f == '.' or $f == '..')
					continue;
				
				if (is_dir($_src.$f))
				{
					if (!$this->copydir($_src.$f, $_dest.$f))
						return false;
				}
				elseif (is_file($_src.$f))
				{
					if (!copy($_src.$f, $_dest.$f))
						return false;
					
					// sets modification date to reflect source's file date
					touch($_src.$f, filemtime($_dest.$f));
				}
			}
			closedir($dh);
		}
		return true;
	}
	
	/**
	 * Returns given filename's extension (eg: jpg, pdf, odt).
	 */
	static function getExtension($filename)
	{
		return substr(strrchr($filename, '.'), 1);
	}
	
	/**
	 * Returns given filename without any extension.
	 */
	static function removeExtension($filename)
	{
		return substr($filename, 0, -strlen(strrchr($filename, '.')));
	}
	
}
?>